<script setup lang="ts">
import { computed, onMounted, reactive } from "vue";
import type { RuleObject } from "ant-design-vue/es/form";
import { Form, message } from "ant-design-vue";
import { handleForm, handleApi } from "@/utils/alert.ts";
import {
  getUserWaybillSubscription,
  getStandardTemplate,
  createUserTemplate,
  getCustomTemplates
} from "@/api/waybill.ts";
import { useSwitchable } from "@/utils/hooks.ts";

export type FormState = {
  title: string;
  branch_code?: string;
  wp_code?: string;
  addr?: string;
  shipper?: string;
  mobile?: string;
  phone?: string;
  standard_template?: string;
  is_default: boolean;
  account_id?: string;
  custom_template?: string;
  sn_id?: number;
}

export type Emits = {
  success: [];
  cancel: []
}

export type OptionsState = {
  waybillSubscriptions: IUserWaybillSubscription[];
  addrs: Partial<IAddress>[];
  templates: IStandardTemplate[];
  customTemplates: ICustomTemplate[];
}

const optionsState = reactive<OptionsState>({
  waybillSubscriptions: [],
  addrs: [],
  templates: [],
  customTemplates: []
})

const { state: loading, update } = useSwitchable(true)


onMounted(async () => {
  const subscriptions = await getUserWaybillSubscription().catch(handleApi)
  update(false)
  optionsState.waybillSubscriptions = subscriptions?.data?.data || []
})

const emit = defineEmits<Emits>()

const formState = reactive<FormState>({
  title: '',
  branch_code: '',
  wp_code: '',
  addr: '',
  shipper: '',
  standard_template: '',
  custom_template: '',
  is_default: false,
  sn_id: undefined,
  selectAddress: {}
})
const formRules = reactive<PartialRecord<FormState, RuleObject[]>>({
  title: [
    { required: true, message: '请输入模板名称' }
  ],
  branch_code: [
    { required: true, message: '请选择网点' }
  ],
  wp_code: [],

  addr: [
    { required: true, message: '选择地址' }
  ],
  shipper: [
    { required: true, message: '请填写发货人' }
  ],
  mobile: [],
  phone: [],
  standard_template: [
    { required: true, message: '请选择标准模板' }
  ],
  custom_template: [
    // { required: true, message: '请选择自定义模板' }
  ],
  is_default: [],
  sn_id: []
})
const { validate, validateInfos, resetFields } = Form.useForm(formState, formRules)

// 缓存电子面单默认模板信息, 防止频繁请求 DY 接口
const cachedCustomTemplate: Record<string, ICustomTemplate[]> = {}

const onSubmit = async () => {

  const res = await validate<FormState>().catch(handleForm)
  if (res) {
    if (!res.phone && !res.mobile) {
      message.error('手机号码和座机号码不能同时为空')
      return
    }
    const addr: IAddress = JSON.parse(res.addr!)
    const template: IStandardTemplate = JSON.parse(res.standard_template!)
    const customTemplate: ICustomTemplate = res.custom_template ? JSON.parse(res.custom_template!) : null
    const data: UserWaybillTemplateCreateReq = {
      title: res.title,
      wp_code: res.wp_code!,
      branch_code: res.branch_code!,
      url: customTemplate?.custom_template_url || '',
      mobile: res.mobile,
      phone: res.phone,
      shipper: res.shipper!,

      province: addr.provinceName,
      province_code: addr.provinceCode,
      city: addr.cityName,
      city_code: addr.cityCode,
      district: addr.districtName,
      district_code: addr.districtCode,
      street_code: addr.streetCode,
      detail: addr.detailAddress,
      standard_template_code: template.standard_template_code,
      // ...addr,
      standard_template_url: template.standard_template_url,
      is_default: res.is_default ? 1 : 2,
      standard_template_id: template.standard_template_id,
      sn_id: res.sn_id!,
    }
    update(true)
    const rp = await createUserTemplate(data).catch(handleApi)
    update(false)
    if (rp) {
      emit('success')
      resetFields()
    }
  }
}

const onBranchChange = async () => {
  const selected = optionsState.waybillSubscriptions.find(i => i.id === formState.sn_id)
  if (selected) {
    formState.selectAddress = selected.address
    formState.branch_code = selected.branch_code
    formState.wp_code = selected.wp_code
    formState.addr = undefined
    formState.standard_template = undefined
    formState.account_id = selected.acount_id
    optionsState.addrs = JSON.parse(selected.address)
    update(true)
    const standTpl = await getStandardTemplate(formState.wp_code).catch(handleApi)
    if (standTpl?.data) {
      optionsState.templates = standTpl.data
    }
    // 优先尝试使用缓存的电子面单默认模板, 如果缓存不存在则调用接口获取
    const cachedToken = `${formState.wp_code}-${formState.account_id}`
    if (cachedCustomTemplate[cachedToken]) {
      optionsState.customTemplates = cachedCustomTemplate[cachedToken]
    } else {
      const customTpl = await getCustomTemplates({ logistics_code: formState.wp_code, acount_id: formState.account_id });
      if (customTpl && customTpl?.data) {
        const tpls: ICustomTemplate[] = []
        customTpl.data.forEach(i => {
          if (i.custom_template_infos?.length) {
            i.custom_template_infos.forEach(j => tpls.push(j))
          }
        })
        cachedCustomTemplate[`${formState.wp_code}-${formState.account_id}`] = tpls
        optionsState.customTemplates = tpls
      }
    }
    update(false)
  }
}

const preview = computed(() => {
  if (formState.standard_template) {
    const template: IStandardTemplate = JSON.parse(formState.standard_template)
    return template.standard_perview_url;
  }
  return ''
})

</script>

<template>
  <div class="flex w-full">
    <div class="flex-none w-3/5">
      <ASpin :spinning="loading">
        <AForm layout="horizontal"
               autocomplete="off"
               :label-col="{ span: 6 }"
               :wrapper-col="{ span: 14 }"
               :model="formState"
               @submit="onSubmit">

          <AFormItem label="模板标题" v-bind="validateInfos.title">
            <AInput v-model:value="formState.title"></AInput>
          </AFormItem>

          <AFormItem label="快递网点" v-bind="validateInfos.branch_code">
            <ASelect v-model:value="formState.sn_id" @change="onBranchChange">
              <ASelectOption v-for="subscription of optionsState.waybillSubscriptions" :value="subscription.id">
                {{ subscription.branch_name }}【{{ subscription.acount_name }}】
              </ASelectOption>
            </ASelect>
          </AFormItem>

          <AFormItem label="发货地址" v-bind="validateInfos.addr">
            <ASelect v-model:value="formState.addr">
              <ASelectOption v-for="addr of optionsState.addrs" :value="JSON.stringify(addr)">
<!--                {{ addr.country }}-->
<!--                {{ addr.province }}-->
<!--                {{ addr.city }}-->
<!--                {{ addr.district }}-->
<!--                {{ addr.detail }}-->
                {{ addr.provinceName }}
                {{ addr.cityName }}
                {{ addr.districtName }}
                {{ addr.streetName }}
                {{ addr.detailAddress }}
              </ASelectOption>
            </ASelect>
          </AFormItem>

          <AFormItem label="发货人" v-bind="validateInfos.shipper">
            <AInput v-model:value="formState.shipper"></AInput>
          </AFormItem>

          <AFormItem label="手机号码" v-bind="validateInfos.mobile">
            <AInput v-model:value="formState.mobile"></AInput>
          </AFormItem>

          <AFormItem label="座机号码" v-bind="validateInfos.phone">
            <AInput v-model:value="formState.phone"></AInput>
          </AFormItem>

          <AFormItem label="标准模板" v-bind="validateInfos.standard_template">
            <ASelect v-model:value="formState.standard_template">
              <ASelectOption v-for="template of optionsState.templates" :value="JSON.stringify(template)">
                {{ template.standard_template_name }}
              </ASelectOption>
            </ASelect>
          </AFormItem>

          <AFormItem label="自定义模板" v-bind="validateInfos.custom_template">
            <ASelect v-model:value="formState.custom_template">
              <ASelectOption value="{}">无</ASelectOption>
              <ASelectOption v-for="template of optionsState.customTemplates" :value="JSON.stringify(template)">
                {{ template.custom_template_name }}
              </ASelectOption>
            </ASelect>
          </AFormItem>

          <AFormItem :wrapper-col="{ offset: 6, span: 14 }" v-bind="validateInfos.is_default">
            <ACheckbox v-model:checked="formState.is_default">设为默认</ACheckbox>
          </AFormItem>

          <AFormItem :wrapper-col="{ offset: 6, span: 14 }">
            <div class="flex justify-end space-x-2">
              <AButton type="primary" html-type="submit">添加</AButton>
              <AButton @click="emit('cancel')">取消</AButton>
            </div>
          </AFormItem>
        </AForm>
      </ASpin>
    </div>

    <div class="flex-grow border-l border-gray-200 h-full py-4 flex flex-col items-center justify-center">
      <div class="text-lg py-2 text-gray-700">标准模板预览图</div>
      <AImage :src="preview" :height="350" v-if="preview"></AImage>
      <AEmpty v-else description="无预览" class="my-10"></AEmpty>
    </div>
  </div>
</template>